#include "../include/KeyRecommander.h"
#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <queue>
#include <cmath>

KeyRecommander::KeyRecommander()
{
    std::cout << "创建关键字推荐器" << std::endl;
    loadDictAndIndex();
}

// 编辑距离算法
int KeyRecommander::editDistance(const std::string &word1, const std::string &word2)
{
    int m = word1.size();
    int n = word2.size();

    // 创建动态规划表
    std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n + 1, 0));

    // 初始化
    for (int i = 0; i <= m; ++i)
    {
        dp[i][0] = i;
    }
    for (int j = 0; j <= n; ++j)
    {
        dp[0][j] = j;
    }

    // 动态规划计算编辑距离
    for (int i = 1; i <= m; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            int insert_cost = dp[i - 1][j] + 1;
            int delete_cost = dp[i][j - 1] + 1;
            int replace_cost = dp[i - 1][j - 1] + (word1[i - 1] != word2[j - 1] ? 1 : 0);

            dp[i][j] = std::min({insert_cost, delete_cost, replace_cost});
        }
    }

    return dp[m][n];
}

// 加载词典库和索引库
void KeyRecommander::loadDictAndIndex()
{
    std::cout << "📚 加载词典库和索引库..." << std::endl;

    // 加载中文词典
    loadChineseDict();

    // 加载英文词典
    loadEnglishDict();

    loadChineseIndex(); // 新增
    loadEnglishIndex(); // 新增
    std::cout << "✅ 词典库加载完成，中文词汇: " << _chinese_dict.size()
              << ", 英文词汇: " << _english_dict.size() << std::endl;
}
void KeyRecommander::loadChineseIndex()
{
    std::ifstream file("../output/index_cn.dat");
    if (!file.is_open())
    {
        std::cerr << "❌ 无法打开中文索引文件: output/index_cn.dat" << std::endl;
        return;
    }

    std::string line;
    while (std::getline(file, line))
    {
        std::istringstream iss(line);
        int index_id;
        std::string character;
        iss >> index_id >> character;

        // 读取该字符对应的词ID列表
        int word_id;
        while (iss >> word_id)
        {
            _chinese_index[character].insert(word_id);
        }
    }
    file.close();
    std::cout << "✅ 中文索引库加载: " << _chinese_index.size() << " 个字符" << std::endl;
}
void KeyRecommander::loadEnglishIndex()
{
    std::ifstream file("../output/index_en.dat");
    if (!file.is_open())
    {
        std::cerr << "❌ 无法打开英文索引文件: output/index_en.dat" << std::endl;
        return;
    }

    std::string line;
    while (std::getline(file, line))
    {
        std::istringstream iss(line);
        int index_id;
        std::string character;
        iss >> index_id >> character;

        // 读取该字符对应的词ID列表
        int word_id;
        while (iss >> word_id)
        {
            _english_index[character].insert(word_id);
        }
    }
    file.close();
    std::cout << "✅ 英文索引库加载: " << _english_index.size() << " 个字母" << std::endl;
}
void KeyRecommander::loadChineseDict()
{
    std::ifstream file("../output/dict_cn.dat");
    if (!file.is_open())
    {
        std::cerr << "❌ 无法打开中文词典文件: output/dict_cn.dat" << std::endl;
        return;
    }

    std::string line;
    while (std::getline(file, line))
    {
        std::istringstream iss(line);
        int id;
        std::string word;
        int freq;

        if (iss >> id >> word >> freq)
        {
            _chinese_dict[word] = freq;
        }
    }
    file.close();
}

void KeyRecommander::loadEnglishDict()
{
    std::ifstream file("../output/dict_en.dat");
    if (!file.is_open())
    {
        std::cerr << "❌ 无法打开英文词典文件: output/dict_en.dat" << std::endl;
        return;
    }

    std::string line;
    while (std::getline(file, line))
    {
        std::istringstream iss(line);
        int id;
        std::string word;
        int freq;

        if (iss >> id >> word >> freq)
        {
            _english_dict[word] = freq;
        }
    }
    file.close();
}

// 候选词结构，用于排序
struct Candidate
{
    std::string word;
    int edit_dist;
    int frequency;

    // 重载小于运算符，用于优先队列排序
    bool operator<(const Candidate &other) const
    {
        // 优先比较编辑距离
        if (edit_dist != other.edit_dist)
        {
            return edit_dist > other.edit_dist; // 编辑距离小的优先
        }
        // 编辑距离相同，比较词频
        if (frequency != other.frequency)
        {
            return frequency < other.frequency; // 词频高的优先
        }
        // 词频相同，按字典序
        return word > other.word; // 字典序小的优先
    }
};

void KeyRecommander::doQuery(const std::string &keyword, std::vector<std::string> &suggestions)
{
    std::cout << "🔍 执行关键字推荐: " << keyword << std::endl;

    bool is_chinese = isChineseKeyword(keyword);
    auto &dict = is_chinese ? _chinese_dict : _english_dict;
    // 详细检查关键词是否在词典中
    auto it = dict.find(keyword);
    if (it != dict.end())
    {
        std::cout << "🎯 关键词 '" << keyword << "' 在词典中，词频: " << it->second << std::endl;
    }
    else
    {
        std::cout << "⚠️  关键词 '" << keyword << "' 不在词典中" << std::endl;
        // 可以在这里添加逻辑：即使不在词典中也尝试推荐
    }

    auto &index = is_chinese ? _chinese_index : _english_index;

    std::cout << "📊 搜索" << (is_chinese ? "中文" : "英文")
              << "词典，使用索引库优化..." << std::endl;

    // 使用优先队列存储候选词
    std::priority_queue<Candidate> candidates;

    // 首先检查关键词本身是否在词典中
    bool keyword_exists = (dict.find(keyword) != dict.end());
    if (keyword_exists)
    {
        std::cout << "🎯 关键词 '" << keyword << "' 在词典中，词频: " << dict[keyword] << std::endl;
        // 将关键词本身作为最高优先级候选
        candidates.push({keyword, -1000, dict[keyword]}); // 极低优先级值，确保排第一
    }

    // !!! 关键优化：英文限制处理数量 !!!
    int MAX_PROCESS = is_chinese ? 500 : 1000; // 英文限制1000个词
    int processed = 0;

    // 方法1：通过索引库找到包含相同字符的词
    std::set<std::string> index_candidates;

    if (is_chinese)
    {
        // 中文：对每个汉字查找索引
        for (size_t i = 0; i < keyword.size();)
        {
            if (i + 3 <= keyword.size())
            { // UTF-8 中文字符
                std::string ch = keyword.substr(i, 3);
                if (index.find(ch) != index.end())
                {
                    // 通过索引找到包含该字符的词
                    for (int word_id : index[ch])
                    {
                        // 这里需要根据word_id找到对应的词
                        // 简单映射：遍历词典找到对应位置的词
                        int current_id = 1;
                        for (const auto &[word, freq] : dict)
                        {
                            if (current_id == word_id)
                            {
                                if (word != keyword)
                                { // 排除关键词本身（已经添加过了）
                                    index_candidates.insert(word);
                                }
                                break;
                            }
                            current_id++;
                        }
                    }
                }
                i += 3;
            }
            else
            {
                i += 1;
            }
        }
    }
    else
    {
        // 英文：只处理前几个字符的索引，避免处理太多
        int max_chars_to_process = std::min(3, (int)keyword.size());
        for (int i = 0; i < max_chars_to_process; i++)
        {
            std::string ch(1, tolower(keyword[i]));
            if (index.find(ch) != index.end())
            {
                // 限制每个字符处理的词数量
                int word_count = 0;
                for (int word_id : index[ch])
                {
                    if (word_count++ >= 200)
                        break; // 每个字符最多200个词

                    int current_id = 1;
                    for (const auto &[word, freq] : dict)
                    {
                        if (current_id == word_id)
                        {
                            if (word != keyword)
                            {
                                index_candidates.insert(word);
                            }
                            break;
                        }
                        current_id++;
                    }
                }
            }
        }
    }

    std::cout << "🎯 通过索引库找到 " << index_candidates.size() << " 个候选词" << std::endl;

    // 方法2：结合编辑距离和索引库结果
    // int processed = 0;
    // const int MAX_PROCESS = 500;

    // 优先处理索引库找到的词
    for (const auto &word : index_candidates)
    {
        if (processed++ >= MAX_PROCESS)
            break;

        int dist = editDistance(keyword, word);
        int freq = dict[word];

        // 改进的优先级计算：
        // 1. 相同字符数量权重最高（语义相关）
        int same_chars = countSameCharacters(keyword, word, is_chinese);
        // 2. 编辑距离权重次之
        // 3. 词频权重最低（避免总是推荐高频通用词）

        int priority = dist * 5 - same_chars * 100 - freq / 10;

        candidates.push({word, priority, freq});
    }
    // 如果候选词不足，补充词典中的词
    if (candidates.size() < 10)
    {
        for (const auto &[word, freq] : dict)
        {
            if (word == keyword)
                continue; // 已经添加过了
            if (processed++ >= MAX_PROCESS)
                break;
            if (index_candidates.find(word) != index_candidates.end())
                continue;

            int dist = editDistance(keyword, word);
            int same_chars = countSameCharacters(keyword, word, is_chinese);
            int priority = dist * 100 - same_chars * 50 - freq;

            candidates.push({word, priority, freq});
        }
    }

    // 提取结果
    std::vector<std::string> all_suggestions;

    // 首先确保关键词本身在结果中（如果存在）
    if (keyword_exists)
    {
        all_suggestions.push_back(keyword);
    }

    // 然后添加其他候选词
    while (!candidates.empty() && all_suggestions.size() < 10)
    {
        auto candidate = candidates.top();
        // 避免重复添加关键词本身
        if (candidate.word != keyword)
        {
            all_suggestions.push_back(candidate.word);
        }
        candidates.pop();
    }

    // 取前5个
    for (size_t i = 0; i < std::min(size_t(5), all_suggestions.size()); ++i)
    {
        suggestions.push_back(all_suggestions[i]);

        // 显示推荐理由
        std::string reason = (all_suggestions[i] == keyword) ? "完全匹配" : "相似推荐";
        std::cout << "  推荐 " << (i + 1) << ": '" << all_suggestions[i]
                  << "' (" << reason << ", 词频=" << dict[all_suggestions[i]] << ")" << std::endl;
    }

    std::cout << "✅ 生成 " << suggestions.size() << " 个推荐" << std::endl;
}

// 计算两个词相同字符的数量
int KeyRecommander::countSameCharacters(const std::string &word1, const std::string &word2, bool is_chinese)
{
    int count = 0;

    if (is_chinese)
    {
        // 中文：按顺序比较相同位置的汉字
        size_t i = 0, j = 0;
        while (i < word1.size() && j < word2.size())
        {
            if (i + 3 <= word1.size() && j + 3 <= word2.size())
            {
                std::string ch1 = word1.substr(i, 3);
                std::string ch2 = word2.substr(j, 3);
                if (ch1 == ch2)
                {
                    count += 3; // 相同汉字给更高权重
                    i += 3;
                    j += 3;
                }
                else
                {
                    // 尝试跳过不匹配的字符
                    i += 3;
                }
            }
            else
            {
                i += 1;
                j += 1;
            }
        }
    }
    else
    {
        // 英文：按顺序比较相同位置的字母
        size_t min_len = std::min(word1.size(), word2.size());
        for (size_t i = 0; i < min_len; i++)
        {
            if (tolower(word1[i]) == tolower(word2[i]))
            {
                count += 2; // 相同位置字母给更高权重
            }
        }

        // 额外加分：包含相同字母（不考虑位置）
        for (char c1 : word1)
        {
            for (char c2 : word2)
            {
                if (tolower(c1) == tolower(c2))
                {
                    count += 1;
                    break;
                }
            }
        }
    }

    return count;
}

// 补充高频词（当编辑距离筛选结果不足时）
void KeyRecommander::supplementWithHighFrequencyWords(const std::string &keyword,
                                                      std::vector<std::string> &suggestions,
                                                      const std::map<std::string, int> &dict)
{
    std::vector<std::pair<std::string, int>> high_freq_words;

    for (const auto &[word, freq] : dict)
    {
        // 跳过已经存在的词
        if (std::find(suggestions.begin(), suggestions.end(), word) != suggestions.end())
        {
            continue;
        }

        // 选择高频词
        if (freq > 10)
        { // 词频阈值
            high_freq_words.emplace_back(word, freq);
        }
    }

    // 按词频排序
    std::sort(high_freq_words.begin(), high_freq_words.end(),
              [](const auto &a, const auto &b)
              {
                  return a.second > b.second;
              });

    // 补充到推荐列表中
    int needed = 5 - suggestions.size();
    for (int i = 0; i < needed && i < high_freq_words.size(); ++i)
    {
        suggestions.push_back(high_freq_words[i].first);
        std::cout << "  补充高频词: '" << high_freq_words[i].first
                  << "' (词频=" << high_freq_words[i].second << ")" << std::endl;
    }
}
bool KeyRecommander::isChineseKeyword(const std::string &word)
{
    if (word.empty())
        return false;

    // 更准确的中文判断：检查UTF-8编码
    int chinese_chars = 0;
    for (size_t i = 0; i < word.size();)
    {
        unsigned char c = word[i];
        if ((c & 0xE0) == 0xE0 && i + 2 < word.size())
        { // 中文UTF-8: 1110xxxx
            chinese_chars++;
            i += 3;
        }
        else
        {
            i += 1;
        }
    }
    return chinese_chars > 0;
}